package whf.framework.util;

import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import whf.framework.entity.Entity;
import whf.framework.web.Constants;

/**
 * @author wanghaifeng
 * 
 */
public class ParamUtils {

	public static String getParameter(HttpServletRequest request, String name) {
		return getParameter(request, name, false);
	}

	public static String getParameter(HttpServletRequest request, String name, boolean emptyStringsOK) {
		String temp = request.getParameter(name);
		if(StringUtils.isEmpty(temp)) {
			temp = request.getParameter(Constants.REQUEST_KEEP_PARAMETER_PREFFIX + name);
		}
		if (temp != null) {
			if (temp.equals("") && !emptyStringsOK) {
				return null;
			} else {
				return temp;
			}
		} else {
			return null;
		}
	}
	
	public static String[] getParameterValues(HttpServletRequest request, String name) {
		String[] values1 = request.getParameterValues(name);
		String[] values2 = request.getParameterValues(Constants.REQUEST_KEEP_PARAMETER_PREFFIX + name);
		String[] values = new String[(values1 == null?0:values1.length) + (values2 == null? 0: values2.length)];
		if(values1 != null) {
			for(int i=0; i< values1.length; i++){
				values[i] = values[1];
			}
		}
		if(values2 != null) {
			int start = values1 == null?0: values1.length;
			for(int i= start; i< start + values2.length; i++){
				values[i] = values2[i - start];
			}
		}
		return values;
	}

	public static boolean getBooleanParameter(HttpServletRequest request, String name) {
		return getBooleanParameter(request, name, false);
	}

	public static boolean getBooleanParameter(HttpServletRequest request, String name, boolean defaultVal) {
		String temp = getParameter(request, name);
		if ("true".equals(temp) || "on".equals(temp)) {
			return true;
		} else if ("false".equals(temp) || "off".equals(temp)) {
			return false;
		} else {
			return defaultVal;
		}
	}

	public static int getIntParameter(HttpServletRequest request, String name, int defaultNum) {
		String temp = getParameter(request, name);
		if (temp != null && !temp.equals("")) {
			int num = defaultNum;
			try {
				num = Integer.parseInt(temp);
			} catch (Exception ignored) {
			}
			return num;
		} else {
			return defaultNum;
		}
	}

	public static int[] getIntParameters(HttpServletRequest request, String name, int defaultNum) {
		String[] paramValues = getParameterValues(request, name);
		if (paramValues == null) {
			return null;
		}
		if (paramValues.length < 1) {
			return new int[0];
		}
		int[] values = new int[paramValues.length];
		for (int i = 0; i < paramValues.length; i++) {
			try {
				values[i] = Integer.parseInt(paramValues[i]);
			} catch (Exception e) {
				values[i] = defaultNum;
			}
		}
		return values;
	}

	public static double getDoubleParameter(HttpServletRequest request, String name, double defaultNum) {
		String temp = getParameter(request, name);
		if (temp != null && !temp.equals("")) {
			double num = defaultNum;
			try {
				num = Double.parseDouble(temp);
			} catch (Exception ignored) {
			}
			return num;
		} else {
			return defaultNum;
		}
	}

	public static long getLongParameter(HttpServletRequest request, String name, long defaultNum) {
		String temp = getParameter(request, name);
		if (temp != null && !temp.equals("")) {
			long num = defaultNum;
			try {
				num = Long.parseLong(temp);
			} catch (Exception ignored) {
			}
			return num;
		} else {
			return defaultNum;
		}
	}

	public static long[] getLongParameters(HttpServletRequest request, String name, long defaultNum) {
		String[] paramValues = getParameterValues(request, name);
		if (paramValues == null) {
			return null;
		}
		if (paramValues.length < 1) {
			return new long[0];
		}
		long[] values = new long[paramValues.length];
		for (int i = 0; i < paramValues.length; i++) {
			try {
				values[i] = Long.parseLong(paramValues[i]);
			} catch (Exception e) {
				values[i] = defaultNum;
			}
		}
		return values;
	}

	public static String getAttribute(HttpServletRequest request, String name) {
		return getAttribute(request, name, false);
	}

	public static String getAttribute(HttpServletRequest request, String name, boolean emptyStringsOK) {
		String temp = (String) request.getAttribute(name);
		if (temp != null) {
			if (temp.equals("") && !emptyStringsOK) {
				return null;
			} else {
				return temp;
			}
		} else {
			return null;
		}
	}

	public static boolean getBooleanAttribute(HttpServletRequest request, String name) {
		String temp = (String) request.getAttribute(name);
		if (temp != null && temp.equals("true")) {
			return true;
		} else {
			return false;
		}
	}

	public static int getIntAttribute(HttpServletRequest request, String name, int defaultNum) {
		String temp = (String) request.getAttribute(name);
		if (temp != null && !temp.equals("")) {
			int num = defaultNum;
			try {
				num = Integer.parseInt(temp);
			} catch (Exception ignored) {
			}
			return num;
		} else {
			return defaultNum;
		}
	}

	public static long getLongAttribute(HttpServletRequest request, String name, long defaultNum) {
		String temp = (String) request.getAttribute(name);
		if (temp != null && !temp.equals("")) {
			long num = defaultNum;
			try {
				num = Long.parseLong(temp);
			} catch (Exception ignored) {
			}
			return num;
		} else {
			return defaultNum;
		}
	}

	/**
	 * 获取tableTag中属性名称前缀
	 * 如属性前缀为pre,属性名称为name，tabletag中输出的属性为"prename"，主要用来区分同一个page中多个tabletag的同名属性的情况
	 * 
	 * @param request
	 * @param type
	 * @return
	 */
	public static String getNamePrefix(HttpServletRequest request, Class type) {
		String namePrefix = request.getParameter(type.getName() + Constants.NAME_PREFIX); // get
																							// the
																							// name
																							// prefix
		if (namePrefix == null)
			namePrefix = "";
		return namePrefix;
	}

	/**
	 * 是否使用主键作为属性名称后缀，对于tabletag中列表显示，如果要求修改的话，用来识别每一个对象；
	 * 
	 * @param request
	 * @param type
	 * @return
	 */
	public static boolean isPkSuffix(HttpServletRequest request, Class type) {
		return ParamUtils.getBooleanParameter(request, type.getName() + Constants.PK_SUFFIX); // whether
																								// is
																								// pk
																								// suffix
	}

	/**
	 * 根据命名规则获取所有对象的id,适用于delete id获取等
	 * 
	 * @param request
	 * @param type
	 * @param defaultValue
	 * @return
	 */
	public static long[] getIds(HttpServletRequest request, Class type, long defaultValue) {
		String namePrefix = getNamePrefix(request, type);
		boolean pkSuffix = isPkSuffix(request, type);
		if (!pkSuffix) {
			return getLongParameters(request, namePrefix + Constants.ID, defaultValue);
		} else {
			LongList list = new LongList();
			List<String> paramNames = getParameterNames(request);
			for (String paramName : paramNames) {
				if (paramName.startsWith(namePrefix + Constants.ID)) {
					long[] values = getLongParameters(request, paramName, 0);
					list.addAll(values);
				}
			}
			return list.toArray();
		}
	}

	/**
	 * 获取一个普通属性的String值
	 * 
	 * @param request
	 * @param type
	 * @param property
	 * @param pk
	 * @return
	 */
	public static String getCommonParameter(HttpServletRequest request, Class type, String property, long pk) {
		String namePrefix = getNamePrefix(request, type);
		boolean pkSuffix = isPkSuffix(request, type);
		if (!pkSuffix) {
			return getParameter(request, namePrefix + property);
		} else {
			return getParameter(request, namePrefix + property + pk);
		}
	}

	public static String getCommonParameter(HttpServletRequest request, Class type, String property) {
		String namePrefix = getNamePrefix(request, type);
		boolean pkSuffix = isPkSuffix(request, type);
		if (!pkSuffix) {
			String p = getParameter(request, namePrefix + property);
			if (StringUtils.isEmpty(p)) {
				p = getParameter(request, namePrefix + property + Constants.BOID_SUFFIX); // 适用于字符串绑定业务对象的情况，省去meta检查
			}
			return p;
		} else {
			long[] pks = getIds(request, type, 0);
			long pk = 0;
			if (pks != null && pks.length > 0) {
				pk = pks[0];
			}
			String p = getParameter(request, namePrefix + property + pk);
			if (StringUtils.isEmpty(p)) {
				p = getParameter(request, namePrefix + property + pk + Constants.BOID_SUFFIX);
			}
			return p;
		}
	}

	/**
	 * @param request
	 * @param propertyType
	 * @param propertyName
	 * @param defaultValue
	 * @param boId
	 *            当前正在操作（创建或修改）对象的id
	 * @return
	 */
	public static long getManyToOnePropertyId(HttpServletRequest request, Class propertyType, String propertyName, long defaultValue, long boId) {
		String namePrefix = getNamePrefix(request, propertyType);
		boolean pkSuffix = isPkSuffix(request, propertyType);
		if (!pkSuffix) {
			return getLongParameter(request, namePrefix + propertyName + Constants.BOID_SUFFIX, defaultValue);
		} else {
			List<String> paramNames = getParameterNames(request);
			String parameterName = namePrefix + propertyType + boId + Constants.BOID_SUFFIX;
			for (String paramName : paramNames) {
				if (paramName.equals(parameterName)) {
					return getLongParameter(request, paramName, defaultValue);
				}
			}
			return defaultValue;
		}
	}

	/**
	 * 对于Collection属性的多选或者单选时所有业务属性中对象的id； 获取时需要考虑tabletag的namePrefix和pksuffix属性
	 * 
	 * @param request
	 * @param bo
	 * @param propertyName
	 * @param defaultValue
	 * @return
	 */
	public static long[] getCollectionPropertyIds(HttpServletRequest request, Entity bo, String propertyName, long defaultValue) {
		Class boClass = bo.getClass();
		String namePrefix = getNamePrefix(request, boClass);
		boolean pkSuffix = isPkSuffix(request, boClass);
		String paramName = namePrefix + propertyName + Constants.BOID_SUFFIX;
		if (pkSuffix) {
			paramName = namePrefix + propertyName + bo.getId() + Constants.BOID_SUFFIX;
		}
		String paramValue = getParameter(request, paramName);
		LongList list = new LongList();
		if (paramValue != null) {
			String[] ss = StringUtils.split(paramValue, ",");
			for (int i = 0; i < ss.length; i++) {
				try {
					long newId = Long.parseLong(ss[i]);
					if (newId > 0) {
						boolean found = false;
						for (long oldId : list.toArray()) {
							if (oldId == newId) {
								found = true;
								break;
							}
						}
						if (!found) {
							list.add(newId);
						}
					}
				} catch (Exception e) {
					// ignore
				}
			}
		}
		return list.toArray();
	}

	/**
	 * 获取request中所有parameter名称
	 * 
	 * @param request
	 * @return
	 */
	public static List<String> getParameterNames(HttpServletRequest request) {
		List<String> paramNames = new ArrayList<String>();
		Enumeration<String> enumParamNames = request.getParameterNames();
		while (enumParamNames.hasMoreElements()) {
			paramNames.add(enumParamNames.nextElement().toString());
		}
		return paramNames;
	}

	public static Object getAttributeObject(HttpServletRequest request, String attributeName) {
		Object res = request.getAttribute(attributeName);
		if (res == null) {
			res = request.getSession().getAttribute(attributeName);
		}
		return res;
	}

	public static Map<String, String> getKeepParameters(HttpServletRequest request) {
		Enumeration<String> requestParameterNames = request.getParameterNames();
		Map<String, String> resolvedParameters = Utils.newHashMap();
		while (requestParameterNames.hasMoreElements()) {
			String requestParameterName = requestParameterNames.nextElement();
			if (!requestParameterName.startsWith(Constants.REQUEST_KEEP_PARAMETER_PREFFIX))
				continue;
			String requestParameterValue = request.getParameter(requestParameterName);
			resolvedParameters.put(requestParameterName, requestParameterValue);
		}
		return resolvedParameters;
	}
	
	public static String getKeepParameterURI(HttpServletRequest request) {
		Map<String, String> parameters = getKeepParameters(request);
		StringBuilder sb = new StringBuilder();
		for(String key: parameters.keySet()) {
			sb.append(key).append("=").append(parameters.get(key)).append("&");
		}
		return sb.toString();
	}
}